package trabalho3.model;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;

import model.org.jtrace.Material;
import model.org.jtrace.Materials;
import model.org.jtrace.Scene;
import model.org.jtrace.cameras.Camera;
import model.org.jtrace.cameras.PinHoleCamera;
import model.org.jtrace.geometry.Plane;
import model.org.jtrace.geometry.Triangle;
import model.org.jtrace.lights.Light;
import model.org.jtrace.primitives.ColorRGB;
import model.org.jtrace.primitives.Point3D;
import model.org.jtrace.primitives.ReflectanceCoefficient;
import model.org.jtrace.primitives.Vector3D;

public class SceneFactory {
	
	private int sceneType;
	private boolean ativarTextura;
	private boolean ativarBoundingBox;
	private File fileTextura;
	
	public SceneFactory(int sceneType) {
		this.sceneType = sceneType;
	}
	
	public Scene getScene() throws IOException, InterruptedException {
		
		switch (sceneType) {
		case 0:
			return createScene0();
			
		case 1:
			return createScene1();

		default:
			return null;
		}
	}
	
	private Scene createScene0() throws IOException, InterruptedException {
		
		/*InputStream is = new FileInputStream(new File("ply/sphere.ply"));
		List<Triangle> triangles;
 
		triangles = PlyReader.read(is, Materials.matte(ColorRGB.PURPLE));
		Scene scene = new Scene();
		
		for (Triangle t : triangles) {
			scene.add(t);
			
		}
		
		scene.add(new Light(140, -200, 200));
		
		Camera camera = new PinHoleCamera(new Point3D(140, 140, 140), new Point3D(139, 139, 139), Vector3D.UNIT_Z);
		
		camera.setZoomFactor(50);
		
		scene.setCamera(camera);
		final Plane lowerPlane = new Plane(new Point3D(0, -150, -20), new Vector3D(0, 0, 1), Materials.metallic(ColorRGB.YELLOW));
		
		scene.add(lowerPlane);
		
		return scene;*/
		
		MeshSphere meshSphere = new MeshSphere(Materials.metallic(ColorRGB.GREEN), ativarBoundingBox);
		List<Triangle> triangles = meshSphere.getTriangles();
		Scene scene = new Scene();
		
		
		//System.out.println(">>> minPoint = " + meshSphere.getBox().getLower());
		//System.out.println(">>> maxPoint = " + meshSphere.getBox().getUpper());
		
		//Point3D media = meshSphere.getBox().getUpper().add(meshSphere.getBox().getLower()).divide(2.0);
		
		//System.out.println(">>> media = " + media);
		
		
		BufferedImage image = null;
		ImageTexture imageTexture = null;
		
		if (ativarTextura) {
			image = ImageIO.read(fileTextura);
			int width = image.getWidth();
			int height = image.getHeight();
			
			imageTexture = new ImageTexture(image, width, height);
		}
		
		
		if (!ativarBoundingBox) {
			for (Triangle t : triangles) {
				if (ativarTextura) {
					t.getMaterial().setImageTexture(imageTexture);
				}
				
				scene.add(t);
			}
		} else {
			System.out.println(">> MESH SPHERE");
			if (ativarTextura) {
				meshSphere.getMaterial().setImageTexture(imageTexture);
			}
			scene.add(meshSphere);
		}
		
		scene.add(new Light(140, 200, 140));
		//scene.add(new Light(140, 140, 140));
		
		Camera camera = new PinHoleCamera(new Point3D(140, 140, 140), new Point3D(139, 139, 139), Vector3D.UNIT_Z);
		
		camera.setZoomFactor(50);
		
		scene.setCamera(camera);
		final Plane lowerPlane = new Plane(new Point3D(0, -140.1, -15), new Vector3D(0, 0, 1), Materials.metallic(ColorRGB.YELLOW));
		
		scene.add(lowerPlane);
		
		return scene;
		
		//Tracer tracer = new Tracer();
		//Tracer tracer = new MultiThreadTracer(10);
		
		//tracer.addInterceptors(new ShadowInterceptor());
		//tracer.addShaders(Shaders.ambientShader(), Shaders.diffuseShader(), Shaders.specularShader(64));
		
		//tracer.addListeners(new ImageListener("teste5.png", "png"), new TimeListener());
		
		//tracer.render(scene, new ViewPlane(1280, 768));
	}
	
	private Scene createScene1() {
		final Point3D lookAt = new Point3D(0, 0, 0);
        final Point3D eye = new Point3D(-15, -15, 100);
        final Vector3D up = new Vector3D(0, 1, 0);

//        final Point3D centerRed  = new Point3D(0, 0, -10);
//        final Point3D centerBlue = new Point3D(-10, 0, -20);

        final Point3D planePoint = new Point3D(0, 20, 0);
        final Vector3D planeNormal = new Vector3D(0, -1, 0);

        final ReflectanceCoefficient kAmbient = new ReflectanceCoefficient(0.07, 0.07, 0.07);
        final ReflectanceCoefficient kDiffuse = new ReflectanceCoefficient(0.3, 0.3, 0.3);

//        final Material redMaterial = new Material(ColorRGB.GREEN, kAmbient, kDiffuse);
//        final Material blueMaterial = new Material(ColorRGB.BLUE, kAmbient, kDiffuse);
        final Material planeMaterial = new Material(ColorRGB.YELLOW, kAmbient, kDiffuse);

        //final Sphere red = new Sphere(centerRed, 10, redMaterial);
        //final Sphere blue = new Sphere(centerBlue, 10, blueMaterial);

        final CustomPlane plane1 = new CustomPlane(planePoint, planeNormal, planeMaterial);
        final CustomPlane plane2 = new CustomPlane(planePoint.multiply(-1), planeNormal.multiply(-1), planeMaterial);

        final Light light = new Light(0, -20, 10);

        final Camera pinHoleCamera = new PinHoleCamera(eye, lookAt, up);
        pinHoleCamera.setZoomFactor(10);
        return new Scene().add(/*blue, red,*/ plane1, plane2).add(light).setCamera(pinHoleCamera);
	}
	
	public void setAtivarTextura(boolean ativarTextura) {
		this.ativarTextura = ativarTextura;
	}
	
	public void setAtivarBoundingBox(boolean ativarBoundingBox) {
		this.ativarBoundingBox = ativarBoundingBox;
	}
	
	public void setFileTextura(File fileTextura) {
		this.fileTextura = fileTextura;
	}

}
